// util.cpp

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <time.h>
#ifdef __unix__
#include <sys/stat.h>
#endif
#ifdef _WIN32
#include <windows.h>
#endif

#include "config.h"
#include "util.hpp"

// Our main log function, used to store all procedures and errors ocurred
// during the game. Recieves a char with the text we need to output.
void log_entry(const char *text)
{
   std::string path;
   time_t now = time(NULL);
   struct tm *tm = localtime(&now);

   // Our path is the configuration directory location plus the log file
   // location.
   path = get_confdir() + "/log.txt";

   // Open the file.
   std::ofstream out(path.c_str(), std::ios::app);

   // If there was an error, print it!
   if (out == NULL)
      fprintf(stderr, "WARNING: unable to open log file in %s\n", path.c_str());

   // We print the date and time in the file.
   out << 1900 + tm->tm_year << '/' << tm->tm_mon + 1 << '/' << tm->tm_mday
       << ' ' << tm->tm_hour << ':' << tm->tm_min << ':' << tm->tm_sec << ": ";

   // Write the text after the time.
   out << text << std::endl;
   // Print it in the screen.
   std::cerr << text << std::endl;

   // Close our file.
   out.close();
}

// Return a string containing where user's home directory is, depending on
// the OS and other variables. Returns the home location.
std::string get_homedir()
{
   std::string home;

   // If we are in Linux...
#ifdef __unix__
   // Get the path where the home directory is (/home/user).
   home = std::string(getenv("HOME"));
#endif
   // If we are Windows...
#ifdef _WIN32
   // Get the user's directory location. This sometimes can't work, so other
   // environment variables are available, such as HOMEPATH or HOMEDRIVE.

   /*********************************************/
   /***** HOME CAN'T BE COMPARED WITH NULL! *****/
   /************** CHECK THAT!!! ****************/
   /*********************************************/
   
   home = std::string(getenv("USERPROFILE"));

   // If we couldn't get USERPROFILE, try with HOMEPATH.
   if (home.length == 0)
      home = std::string(getenv("HOMEPATH"));

   // If we still couldn't get our path, try with HOMEDRIVE.
   if (home.length == 0)
      home = std::string(getenv("HOMEDRIVE"));
#endif

   return home;
}

// Get the configuration directory location in the file system. Uses the
// get_homedir() function to get the user's home location. Returns a string.
std::string get_confdir()
{
   std::string confdir;

   // Our confdir is the combination of the user's home, plus the hidden
   // project name (stored in the CMake generated config.h).
   confdir = get_homedir() + "/." + PROJECT_LOWER;

   return confdir;
}

// Setup all configuration related things. Create a hidden directory (.game)
// where we store all our configuration variables, logs etc.
void create_confdir()
{
   std::string confdir;
   std::string rmlog;

   // In a string we store the configuration directory location. 
   confdir = get_confdir();

   // If we are under Linux...
#ifdef __unix__
   // ...use the sys/stat.h library to create a new folder. If it fails,
   // return an error. (NOTE: the content of the string must be obtained from
   // calling c_str() function!).
   if (mkdir(confdir.c_str(), 0775) != 0)
      fprintf(stderr, "INFO: Configuration directory already exists.\n");
#endif

   // If we are under Windows...
#ifdef _WIN32
   // ...using the windows.h library, create a new folder as we did with
   // Linux. (TODO: test it!).
   if (CreateDirectory(confdir.c_str, NULL) == NULL)
      fprintf(stderr, "INFO: Configuration directory already exists.\n");
#endif

   // Remove the last instance log.
   rmlog = confdir + "/log.txt";
   if (remove(rmlog.c_str()) != 0)
      log_entry("WARNING: Unable to remove last instance log.");
}

// Parse all command line arguments.
void parse_arguments(int argc, char *argv[])
{
   // If we have enough arguments...
   if (argc > 1) {
      int i;
      // Make this for every argument (number of arguments is stored in the
      // argc variable, its content is in the argv array).
      for (i = 1; i < argc; i++) { // We compare the content of the array with
                                   // the total of possible options.
         if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
            std::cout << "Usage: " << argv[0] << " <OPTIONS> ..." << std::endl;
            // Display help
            puts ("\n"
                  "Display Options:\n"
                  "  -f --fullscreen          starts in fullscreen mode\n"
                  "  -w --windowed            in windowed mode\n"
                  "\n"
                  "Misc Options:\n"
                  "  -h --help                shows this help\n"
                  "  -u --usage               shows a brief message explaining the usage\n"
                  "  -v --version             displays game version\n");
         } else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--fullscreen") == 0) {
            log_entry("INFO: Setting fullscreen mode by command line.");
            return;
         } else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--windowed") == 0) {
            log_entry("INFO: Setting windowed mode by command line.");
            return;
         } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
         } else if (strcmp(argv[i], "-u") == 0 || strcmp(argv[i], "--usage") == 0) {
            // Displays a brief message explaining the usage.
            std::cout << "Usage: " << argv[0] << " <OPTIONS> ..." << std::endl;
         } else {
            // The option made by the user doesn't match anyone, print a
            // message informing the user and exit function.
            std::cout << "Unknown option: " << argv[i] << std::endl;
            return;
         }
      }
      
      exit(0);
   }
}
